﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using RapidAddition.FIXDataDictionary;

namespace LiquidTrading.RapidAdditionHelper.Storage.LiquidView
{
    /// <summary>
    /// Handles everything to do with message storage for Sterling into Liquid View
    /// </summary>
    public sealed class SterlingStorage : IStorage, IDisposable
    {
        public SterlingStorage(string clientName)
        {
            ClientName = clientName;
            m_Linq = new LiquidViewLinqDataContext();
        }

        readonly List<string> LSE_EUROSTOCKS = new List<string>() { "RYA.LN", "CRH.LN", "ALBK.LN", "BKIR.LN" };
        const int TAG_TIF = 59;
        LiquidViewLinqDataContext m_Linq;
        public string ClientName { get; set; }

        #region IStorage Members

        public void ProcessExecutionReportFIX42(RapidAddition.FIXDataDictionary.CFIXDataDictionary dic, RapidAddition.FIXEngine.CFIXMessage exec)
        {            
            CFIXTagValue tag;

            if(exec.TagValuesParsed.TryGetValue(TAG_TIF, out tag))
            {                
                try
                {
                    var tif = RapidAddition.FIXObjectModel.FIX42.CTimeInForce.FromFIX(tag.Value);
                }
                catch
                {
                    m_Linq.LogGeneral(ClientName, "ProcessExecutionReport", "Failed to parse " + tag.Value + " to ETimeInForce so setting it to 0(DAY)", exec.Message, null, null, null, null, null, null);
                    tag.Value = "0";
                }                   
            }

            RapidAddition.FIXObjectModel.FIX42.CMsgExecutionReport msg = null;

            try
            {
                msg = new RapidAddition.FIXObjectModel.FIX42.CMsgExecutionReport(dic, exec);
            }
            catch(Exception e)
            {
                m_Linq.ExceptionHandlerThrow(ClientName, "ProcessExecutionReport Failed to decode message into an CMsgExecutionReport Exception("+ e.Message +") Message(" + exec.Message + ")", null);
                return;
            }

            int tagInteger;
            RapidAddition.FIXObjectModel.FIX42.EExecTransType execTransType;
            if (!msg.ExecTransType.HasValue)
            {
                tag = exec.TagValues.SingleOrDefault(a => a.TagID == 20);
                if (tag != default(CFIXTagValue) && Int32.TryParse(tag.Value, out tagInteger))
                {
                    execTransType = (RapidAddition.FIXObjectModel.FIX42.EExecTransType)tagInteger;
                }
                else if (exec.TagValuesParsed.TryGetValue(20, out tag) && Int32.TryParse(tag.Value, out tagInteger))
                {
                    execTransType = (RapidAddition.FIXObjectModel.FIX42.EExecTransType)tagInteger;
                }
                else
                {
                    m_Linq.ExceptionHandlerThrow(ClientName, "ProcessExecutionReport ExecutionReport has no ExecTransType - " + exec.Message, null);
                    return;
                }
            }
            else
            {
                execTransType = msg.ExecTransType.Value;
            }

            RapidAddition.FIXObjectModel.FIX42.EExecType execType;
            if (!msg.ExecType.HasValue)
            {
                tag = exec.TagValues.SingleOrDefault(a => a.TagID == 150);
                if (tag != default(CFIXTagValue) && Int32.TryParse(tag.Value, out tagInteger))
                {
                    execType = (RapidAddition.FIXObjectModel.FIX42.EExecType)tagInteger;
                }
                else if (exec.TagValuesParsed.TryGetValue(150, out tag) && Int32.TryParse(tag.Value, out tagInteger))
                {
                    execType = (RapidAddition.FIXObjectModel.FIX42.EExecType)tagInteger;

                }
                else
                {
                    m_Linq.ExceptionHandlerThrow(ClientName, "ProcessExecutionReport ExecutionReport has no ExecType - " + exec.Message, null);
                    return;
                }
            }
            else
            {
                execType = msg.ExecType.Value;
            }




            // display type
            Console.WriteLine("ExecTransType: " + execTransType.ToString() + " - ExecType: " + execType.ToString());

            if (execTransType == RapidAddition.FIXObjectModel.FIX42.EExecTransType.eNew)
            {
                if (execType == RapidAddition.FIXObjectModel.FIX42.EExecType.eFill || execType == RapidAddition.FIXObjectModel.FIX42.EExecType.ePartialfill)
                {
                    // get exchange
                    string exchangeMIC = String.Empty;
                    LiquidViewConstants.ExchangeMICs executionExchange = LiquidViewConstants.ExchangeMICs.XXXX; // change to XXXX

                    if (exec.TagValuesParsed.TryGetValue(100, out tag))
                    {
                        exchangeMIC = tag.Value;
                    }
                    else if (msg.SecurityExchange != String.Empty)
                    {
                        exchangeMIC = msg.SecurityExchange;
                    }
                    else if (msg.LastMkt != String.Empty)
                    {
                        exchangeMIC = msg.LastMkt;
                    }

                    // check exchange 
                    if (exchangeMIC == String.Empty)
                    {
                        m_Linq.ExceptionHandlerThrow(ClientName, "ProcessExecutionReport Failed to find an Execution Exchange from MsgExecutionReport(8) setting to default exchange XXXX - " + exec.Message, null);
                    }
                    else if (!TryGetExchangeMIC(exchangeMIC, out executionExchange))
                    {
                        if (!TryGetExchangeMIC(exchangeMIC, exec.SenderCompID, out executionExchange))
                            m_Linq.ExceptionHandlerThrow(ClientName, "ProcessExecutionReport Failed to parse Execution ExchangeMIC for ExDestination=" + exchangeMIC + " - " + exec.Message, null);
                    }


                    // price
                    decimal price = 0;
                    if (msg.LastPx.HasValue)
                    {
                        price = (decimal)msg.LastPx.Value;
                    }
                    else if (msg.AvgPx.HasValue)
                    {
                        price = (decimal)msg.AvgPx.Value;
                    }
                    else if (msg.Price.HasValue)
                    {
                        price = (decimal)msg.Price.Value;
                    }


                    // get currency
                    string currency = msg.Currency;
                    
                    if (currency == "GBp")
                        currency = "GBX";

                    string umtf = String.Empty;
                    string sterlingSymbol = msg.Symbol;
                                       
                    //get umtf symbol for non US exchanges
                    if (!IsUSSymbol(msg.Symbol))
                    {
                        if (executionExchange == LiquidViewConstants.ExchangeMICs.BATS)
                            executionExchange = LiquidViewConstants.ExchangeMICs.BATE;
                        
                        if (exec.SenderCompID == "SFS" && TryGetUMTFfromSterling(msg.Symbol, out umtf))
                        {
                            if (currency == String.Empty)
                            {
                                if (umtf[umtf.Length - 1] == 'l')
                                {
                                    if (LSE_EUROSTOCKS.Contains(msg.Symbol))
                                    {
                                        currency = "EUR";
                                    }
                                    else
                                    {
                                        currency = "GBX";
                                    }
                                }
                                else
                                {
                                    currency = "EUR";
                                }
                            }                            
                        }
                        else if(msg.SecurityIDSource.HasValue
                            && msg.SecurityIDSource.Value == RapidAddition.FIXObjectModel.FIX42.ESecurityIDSource.eISINnumber)
                        {
                            TryGetUMTFFromISIN(executionExchange, currency, msg.SecurityID, msg.Symbol, out umtf);
                        }
                    }

                    // check price
                    if (currency == "GBX" || currency == "GBp")
                    {
                        currency = "GBP";
                        price = price / 100;
                    }



                    // get contraBroker
                    string contraBroker = String.Empty;
                    if (exec.TagValuesParsed.TryGetValue(375, out tag))
                    {
                        contraBroker = tag.Value;
                    }
                    else if (msg.ExecRptCntraBrkrs.Count > 0)
                    {
                        contraBroker = msg.ExecRptCntraBrkrs[0].ContraBroker;
                    }
                    else if (msg.TargetCompID != null && msg.TargetCompID != String.Empty)
                    {
                        contraBroker = msg.TargetCompID;
                    }
                    else if (msg.OnBehalfOfCompID != null && msg.OnBehalfOfCompID != String.Empty)
                    {
                        contraBroker = msg.OnBehalfOfCompID;
                    }
                    else if (exec.TagValuesParsed.TryGetValue(115, out tag) && tag.Value != String.Empty)
                    {
                        contraBroker = tag.Value;
                    }
                    else if (exec.TagValuesParsed.TryGetValue(57, out tag) && tag.Value != String.Empty)
                    {
                        contraBroker = tag.Value;
                    }
                    else if (exec.TagValuesParsed.TryGetValue(100, out tag))
                    {
                        contraBroker = tag.Value;
                    }


                    // account
                    string account = "DEFAULT";
                    if (msg.Account != String.Empty)
                    {
                        if (exec.SenderCompID == "CHIX")
                            msg.Account = msg.Account.Substring(msg.Account.LastIndexOf(':') + 1);

                        if (msg.Account == "NELIQUID")
                            account = "LTI005";
                        else
                            account = msg.Account;
                    }

                    // get text and add messages to it if necessary                    
                    List<string> text = new List<string>();
                    if(msg.Text != String.Empty)
                        text.Add(msg.Text);                    


                    bool isAggressor = false;
                    bool isHidden = false;
                    bool isInternal = false;

                    LiquidViewConstants.ExchangeMICs? routedExchange = null;
                    LiquidViewConstants.TradeTypes? tradeType = null;

                    // get settings from flag
                    string flag9882 = null;
                    if (exec.TagValuesParsed.TryGetValue(9882, out tag))
                    {
                        flag9882 = tag.Value;
                        ParseFlags(exec, executionExchange, ref flag9882, text, out isAggressor, out isHidden, out isInternal, out routedExchange, out tradeType);
                    }

                    // get extra flags and append to TradeText                    
                    // Tag(9621) -- ECNAccessFee
                    if (exec.TagValuesParsed.TryGetValue(9621, out tag))
                    {
                        text.Add("MTFAccessFee(" + tag.Value + ")");
                    }
                    // Tag(9730) -- ECNAccessFee
                    if (exec.TagValuesParsed.TryGetValue(9730, out tag))
                    {
                        text.Add("TradeLiquidityIndicator(" + tag.Value + ")");
                    }

                    // US trade
                    if (LiquidViewConstants.USExchanges.Contains(executionExchange))
                    {
                        if (currency == String.Empty)
                        {
                            currency = "USD";
                        }

                        msg.Symbol = msg.Symbol.Replace('/', '.');

//#if !DEBUG
                        int result = m_Linq.ImportTradeUSStock(
                            ClientName,
                            msg.OrderID,
                            msg.ExecID,
                            executionExchange.ToString(),
                            msg.OrderID,
                            msg.ExecID,
                            account,
                            msg.Symbol,
                            msg.Side == RapidAddition.FIXObjectModel.FIX42.ESide.eBuy ? (long)msg.LastQty.Value : -(long)msg.LastQty.Value,
                            price,
                            msg.TransactTime.Value,
                            contraBroker, // coutnerpart code
                            isAggressor, // is aggressive trade
                            false, // is manual trade
                            isInternal, // is an internalised trade
                            isHidden, // hidden flag
                            tradeType.HasValue ? tradeType.ToString() : null, // trade type
                            null, // broker code
                            String.Join("|", text.ToArray()),
                            routedExchange.HasValue ? routedExchange.ToString() : null, // routed exchange
                            flag9882, // trade flags
                            exec.TargetCompID != String.Empty ? exec.TargetCompID : null); // user

                        if (result == 0)
                        {
                            // trade inserted
                        }
                        else if (result == 1)
                        {
                            m_Linq.ExceptionHandlerThrow(ClientName, "ProcessExecutionReport Filtered(" + result + ") trade on insert of MsgExecutionReport(8) - " + exec.Message, null);
                        }
                        else if (result == -1)
                        {
                            m_Linq.ExceptionHandlerThrow(ClientName, "ProcessExecutionReport Failed(" + result + ") (general) on insert of MsgExecutionReport(8) - " + exec.Message, null);
                        }
                        else if (result == -2)
                        {
                            m_Linq.ExceptionHandlerThrow(ClientName, "ProcessExecutionReport Failed(" + result + ") to find StockId from US stock symbol " + msg.Symbol + " on insert of MsgExecutionReport(8) - " + exec.Message, null);
                        }
                        else if (result == -3)
                        {
                            m_Linq.ExceptionHandlerThrow(ClientName, "ProcessExecutionReport Failed(" + result + ") to find ExchangeMIC of " + exchangeMIC + " on insert of MsgExecutionReport(8) - " + exec.Message, null);
                        }
                        else if (result == -4)
                        {
                            m_Linq.ExceptionHandlerThrow(ClientName, "ProcessExecutionReport Failed(" + result + ") to complete PutTrade on insert of MsgExecutionReport(8) - " + exec.Message, null);
                        }
                        else
                        {
                            m_Linq.ExceptionHandlerThrow(ClientName, "ProcessExecutionReport some other failure(" + result + ") on insert of MsgExecutionReport(8) - " + exec.Message, null);
                        }
//#endif
                        return;

                    }
                    // European or UK trade
                    else
                    {
//#if !DEBUG
                        // try and insert by Sterling symbol
                        int result = m_Linq.ImportTradeBySterlingSymbol(
                            ClientName,
                            msg.OrderID,
                            msg.ExecID,
                            executionExchange.ToString(),
                            msg.OrderID,
                            msg.ExecID,
                            account,
                            currency != String.Empty ? currency : null,
                            sterlingSymbol,
                            msg.Side == RapidAddition.FIXObjectModel.FIX42.ESide.eBuy ? (long)msg.LastQty.Value : -(long)msg.LastQty.Value,
                            price,
                            msg.TransactTime.Value,
                            contraBroker,
                            isAggressor,
                            false,
                            isInternal,
                            String.Empty,
                            String.Join("|", text.ToArray()),
                            isHidden, // hidden flag
                            tradeType.HasValue ? tradeType.ToString() : null, // trade type       
                            routedExchange.HasValue ? routedExchange.ToString() : null, // routed exchange
                            flag9882, // trade flags
                            exec.TargetCompID != String.Empty ? exec.TargetCompID : null); // user

                        string logMessage = String.Empty;

                        if (result == 0)
                        {
                            // trade inserted
                            return;
                        }
                        else if (result == 1)
                        {
                            logMessage = "ProcessExecutionReport ImportTradeByUMTF Filtered(" + result + ") broker trade on insert of MsgExecutionReport(8) - " + exec.Message;
                            return;
                        }
                        else if (result == -1)
                        {
                            logMessage = "ProcessExecutionReport ImportTradeByUMTF Failed(" + result + ")(general) on insert of MsgExecutionReport(8) - " + exec.Message;
                        }
                        else if (result == -2)
                        {
                            logMessage = "ProcessExecutionReport ImportTradeByUMTF Failed(" + result + ") to find StockId from UMTF code " + umtf + " on insert of MsgExecutionReport(8) - " + exec.Message;
                        }
                        else if (result == -3)
                        {
                            logMessage = "ProcessExecutionReport ImportTradeByUMTF Failed(" + result + ") to find ExchangeMIC of " + exchangeMIC + " on insert of MsgExecutionReport(8) - " + exec.Message;
                        }
                        else if (result == -4)
                        {
                            logMessage = "ProcessExecutionReport ImportTradeByUMTF Failed(" + result + ") to find default Local Listing and Currency for " + msg.Symbol + " on " + exchangeMIC + " on insert of MsgExecutionReport(8) - " + exec.Message;
                        }
                        else if (result == -5)
                        {
                            logMessage = "ProcessExecutionReport ImportTradeByUMTF Failed(" + result + ") to complete PutGtrade on insert of MsgExecutionReport(8) - " + exec.Message;
                        }
                        else if (result == -6)
                        {
                            logMessage = "ProcessExecutionReport ImportTradeByUMTF Failed(" + result + ") to complete PutTrade on insert of MsgExecutionReport(8) - " + exec.Message;
                        }
                        else
                        {
                            logMessage = "ProcessExecutionReport ImportTradeByUMTF Failed some other failure(" + result + ") on insert of MsgExecutionReport(8) - " + exec.Message;
                        }

                        // attempt insert by umtf
                        result = m_Linq.ImportTradeByUMTF(
                            ClientName,
                            msg.OrderID,
                            msg.ExecID,
                            executionExchange.ToString(),
                            msg.OrderID,
                            msg.ExecID,
                            account,
                            currency != String.Empty ? currency : null,
                            umtf,
                            msg.Side == RapidAddition.FIXObjectModel.FIX42.ESide.eBuy ? (long)msg.LastQty.Value : -(long)msg.LastQty.Value,
                            price,
                            msg.TransactTime.Value,
                            contraBroker,
                            isAggressor,
                            false,
                            isInternal,
                            String.Empty,
                            String.Join("|", text.ToArray()),
                            isHidden, // hidden flag
                            tradeType.HasValue ? tradeType.ToString() : null, // trade type       
                            routedExchange.HasValue ? routedExchange.ToString() : null, // routed exchange
                            flag9882, // trade flags
                            exec.TargetCompID != String.Empty ? exec.TargetCompID : null); // user

                        if (result == 0)
                        {
                            // trade inserted
                            return;
                        }
                        else if (result == 1)
                        {
                            logMessage = "ProcessExecutionReport ImportTradeByUMTF Filtered(" + result + ") broker trade on insert of MsgExecutionReport(8) - " + exec.Message;
                            return;
                        }
                        else if (result == -1)
                        {
                            logMessage = "ProcessExecutionReport ImportTradeByUMTF Failed(" + result + ")(general) on insert of MsgExecutionReport(8) - " + exec.Message;
                        }
                        else if (result == -2)
                        {
                            logMessage = "ProcessExecutionReport ImportTradeByUMTF Failed(" + result + ") to find StockId from UMTF code " + umtf + " on insert of MsgExecutionReport(8) - " + exec.Message;
                        }
                        else if (result == -3)
                        {
                            logMessage = "ProcessExecutionReport ImportTradeByUMTF Failed(" + result + ") to find ExchangeMIC of " + exchangeMIC + " on insert of MsgExecutionReport(8) - " + exec.Message;
                        }
                        else if (result == -4)
                        {
                            logMessage = "ProcessExecutionReport ImportTradeByUMTF Failed(" + result + ") to find default Local Listing and Currency for " + msg.Symbol + " on " + exchangeMIC + " on insert of MsgExecutionReport(8) - " + exec.Message;
                        }
                        else if (result == -5)
                        {
                            logMessage = "ProcessExecutionReport ImportTradeByUMTF Failed(" + result + ") to complete PutGtrade on insert of MsgExecutionReport(8) - " + exec.Message;
                        }
                        else if (result == -6)
                        {
                            logMessage = "ProcessExecutionReport ImportTradeByUMTF Failed(" + result + ") to complete PutTrade on insert of MsgExecutionReport(8) - " + exec.Message;
                        }
                        else
                        {
                            logMessage = "ProcessExecutionReport ImportTradeByUMTF Failed some other failure(" + result + ") on insert of MsgExecutionReport(8) - " + exec.Message;
                        }       
                        
                        // attempt to insert trade via Market, Currency & Symbol
                        LiquidViewConstants.MarketMIC marketMIC;
                        if (umtf != String.Empty 
                            && LiquidViewConstants.TryGetMarketMICbyUMTF(umtf, out marketMIC))
                        {
                            int? instrumentId = null;

                            result = m_Linq.ImportTradeByMarketCurrencySymbol(
                                ClientName,
                                msg.OrderID,
                                msg.ExecID,
                                executionExchange.ToString(),
                                msg.OrderID,
                                msg.ExecID,
                                account,
                                marketMIC.ToString(),
                                currency != String.Empty ? currency : null,
                                umtf.Substring(0, umtf.Length - 1),
                                msg.Side == RapidAddition.FIXObjectModel.FIX42.ESide.eBuy ? (long)msg.LastQty.Value : -(long)msg.LastQty.Value,
                                price,
                                msg.TransactTime.Value,
                                contraBroker,
                                isAggressor,
                                false,
                                isInternal,
                                String.Empty,
                                String.Join("|", text.ToArray()),
                                isHidden, // hidden flag
                                tradeType.HasValue ? tradeType.ToString() : null, // trade type       
                                routedExchange.HasValue ? routedExchange.ToString() : null, // routed exchange
                                flag9882, // trade flags
                                exec.TargetCompID != String.Empty ? exec.TargetCompID : null,
                                sterlingSymbol,
                                null,
                                null,
                                null); // user


                            if (result == 0)
                            {
                                //do nothing!
                                //m_Linq.ExceptionHandlerThrow(ClientName, "ProcessExecutionReport ImportTradeByMarketCurrencySymbol Success", null);
                                
                                return;
                            }
                            else if (result == 1)
                            {                                
                                m_Linq.ExceptionHandlerThrow(ClientName, "ProcessExecutionReport ImportTradeByMarketCurrencySymbol Filtered(" + result + ") broker trade on insert of MsgExecutionReport(8) - " + exec.Message, null);
                                return;
                            }
                            else if (result == -1)
                            {
                                m_Linq.ExceptionHandlerThrow(ClientName, logMessage, null);
                                m_Linq.ExceptionHandlerThrow(ClientName, "ProcessExecutionReport ImportTradeByMarketCurrencySymbol Failed(" + result + ")(general) on insert of MsgExecutionReport(8) - " + exec.Message, null);
                            }
                            else if (result == -2)
                            {
                                m_Linq.ExceptionHandlerThrow(ClientName, logMessage, null);
                                m_Linq.ExceptionHandlerThrow(ClientName, "ProcessExecutionReport ImportTradeByMarketCurrencySymbol Failed(" + result + ") to find StockId from MarketMIC="+marketMIC+" Currency="+currency+" Symbol=" + umtf.Substring(0, umtf.Length - 1) + " on insert of MsgExecutionReport(8) - " + exec.Message, null);
                            }
                            else if (result == -3)
                            {
                                m_Linq.ExceptionHandlerThrow(ClientName, logMessage, null);
                                m_Linq.ExceptionHandlerThrow(ClientName, "ProcessExecutionReport ImportTradeByMarketCurrencySymbol Failed(" + result + ") to find ExchangeMIC of " + exchangeMIC + " on insert of MsgExecutionReport(8) - " + exec.Message, null);
                            }
                            else if (result == -4)
                            {
                                m_Linq.ExceptionHandlerThrow(ClientName, logMessage, null);
                                m_Linq.ExceptionHandlerThrow(ClientName, "ProcessExecutionReport ImportTradeByMarketCurrencySymbol Failed(" + result + ") to find default Local Listing and Currency for " + msg.Symbol + " on " + exchangeMIC + " on insert of MsgExecutionReport(8) - " + exec.Message, null);
                            }
                            else if (result == -5)
                            {
                                m_Linq.ExceptionHandlerThrow(ClientName, logMessage, null);
                                m_Linq.ExceptionHandlerThrow(ClientName, "ProcessExecutionReport ImportTradeByMarketCurrencySymbol Failed(" + result + ") to complete PutGtrade on insert of MsgExecutionReport(8) - " + exec.Message, null);
                            }
                            else if (result == -6)
                            {
                                m_Linq.ExceptionHandlerThrow(ClientName, logMessage, null);
                                m_Linq.ExceptionHandlerThrow(ClientName, "ProcessExecutionReport ImportTradeByMarketCurrencySymbol Failed(" + result + ") to complete PutTrade on insert of MsgExecutionReport(8) - " + exec.Message, null);
                            }
                            else
                            {
                                m_Linq.ExceptionHandlerThrow(ClientName, logMessage, null);
                                m_Linq.ExceptionHandlerThrow(ClientName, "ProcessExecutionReport ImportTradeByMarketCurrencySymbol Failed, some other failure(" + result + ") on insert of MsgExecutionReport(8) - " + exec.Message, null);
                            }
                        }
                        else
                        {
                            m_Linq.ExceptionHandlerThrow(ClientName, logMessage, null);
                            m_Linq.ExceptionHandlerThrow(ClientName, "ProcessExecutionReport ImportTradeByMarketCurrencySymbol Failed, could not find marketMIC from umtf " + umtf, null);
                        }                        
//#endif

                    }
                }
                // handle new order
                // cancel
                // etc
                // etc
            }
            else if (execTransType == RapidAddition.FIXObjectModel.FIX42.EExecTransType.eCorrect)
            {
                string output = "ExecutionReport has a Correction status: ExecTransType(20)=" + execTransType.ToString() + ", ExecType(150)=" + execType.ToString() + " - " + exec.Message;
                m_Linq.ExceptionHandlerThrow(ClientName, output, null);
                Console.WriteLine(output);
            }
            // else cancel or status message
            // so ignore

        }



        public void ProcessExecutionReportFIX50(RapidAddition.FIXDataDictionary.CFIXDataDictionary dic, RapidAddition.FIXEngine.CFIXMessage exec)
        {
            CFIXTagValue tag;
            RapidAddition.FIXObjectModel.FIX50.CMsgExecutionReport msg = new RapidAddition.FIXObjectModel.FIX50.CMsgExecutionReport(dic, exec);

            if (msg == null)
            {
                m_Linq.ExceptionHandlerThrow(ClientName, "ProcessExecutionReportFIX50 Failed to decode message into an ExecutionReport - " + exec.Message, null);
                return;
            }

            RapidAddition.FIXObjectModel.FIX50.EExecType execType;
            if (!msg.ExecType.HasValue)
            {
                m_Linq.ExceptionHandlerThrow(ClientName, "ProcessExecutionReportFIX50 ExecutionReport has no ExecType - " + exec.Message, null);
                return;
            }
            else
            {
                execType = msg.ExecType.Value;
            }

            // display type
            Console.WriteLine("ExecType: " + execType.ToString());


            if (execType == RapidAddition.FIXObjectModel.FIX50.EExecType.eTradepartialfillorfill)
            {


                // get exchange
                string exchangeMIC = String.Empty;
                LiquidViewConstants.ExchangeMICs executionExchange = LiquidViewConstants.ExchangeMICs.XXXX; // change to XXXX

                if (exec.TagValuesParsed.TryGetValue(100, out tag))
                {
                    exchangeMIC = tag.Value;
                }
                else if (msg.Instrument.SecurityExchange != String.Empty)
                {
                    exchangeMIC = msg.Instrument.SecurityExchange;
                }
                else if (msg.LastMkt != String.Empty)
                {
                    exchangeMIC = msg.LastMkt;
                }
                else if (exec.SenderCompID.Contains("LSE"))
                {
                    exchangeMIC = "LSE";
                }

                // check exchange 
                if (exchangeMIC == String.Empty)
                {
                    m_Linq.ExceptionHandlerThrow(ClientName, "ProcessExecutionReport Failed to find an Execution Exchange from MsgExecutionReport(8) setting to default exchange XXXX - " + exec.Message, null);
                }
                else if (!TryGetExchangeMIC(exchangeMIC, out executionExchange))
                {
                    if (!TryGetExchangeMIC(exchangeMIC, exec.SenderCompID, out executionExchange))
                        m_Linq.ExceptionHandlerThrow(ClientName, "ProcessExecutionReport Failed to parse Execution ExchangeMIC for ExDestination=" + exchangeMIC + " - " + exec.Message, null);
                }

                // price
                decimal price = 0;
                if (msg.LastPx.HasValue)
                {
                    price = (decimal)msg.LastPx.Value;
                }
                else if (msg.AvgPx.HasValue)
                {
                    price = (decimal)msg.AvgPx.Value;
                }
                else if (msg.Price.HasValue)
                {
                    price = (decimal)msg.Price.Value;
                }


                // get currency
                string currency = msg.Currency;

                if (currency == "GBp")
                    currency = "GBX";

                string umtf = String.Empty;

                //get umtf symbol for non US exchanges
                if (!IsUSSymbol(msg.Instrument.Symbol))
                {
                    if(executionExchange == LiquidViewConstants.ExchangeMICs.BATS)
                        executionExchange = LiquidViewConstants.ExchangeMICs.BATE;

                    if (exec.SenderCompID == "SFS" && TryGetUMTFfromSterling(msg.Instrument.Symbol, out umtf))
                    {
                        if (currency == "GBP" && umtf[umtf.Length - 1] == 'l')
                            currency = "GBX";
                    }
                    else if (!(msg.Instrument.SecurityIDSource.HasValue
                        && msg.Instrument.SecurityIDSource.Value == RapidAddition.FIXObjectModel.FIX50.ESecurityIDSource.eISINnumber
                        && TryGetUMTFFromISIN(executionExchange, currency, msg.Instrument.SecurityID, msg.Instrument.Symbol, out umtf)))
                    {
                        if (!(msg.Instrument.SecurityIDSource.HasValue
                        && msg.Instrument.SecurityIDSource.Value == RapidAddition.FIXObjectModel.FIX50.ESecurityIDSource.eExchangeSymbol
                        && executionExchange == LiquidViewConstants.ExchangeMICs.XLON
                        && TryGetUMTFFromISIN(executionExchange, currency == "GBX" ? "GBP" : currency, msg.Instrument.SecurityID.Substring(0, 12), msg.Instrument.Symbol, out umtf)))
                        {
                            umtf = String.Empty;
                        }
                    }
                }

                // check price
                if (currency == "GBX" || currency == "GBp")
                {
                    currency = "GBP";
                    price = price / 100;
                }

                // get contraBroker
                string contraBroker = String.Empty;
                if (exec.TagValuesParsed.TryGetValue(375, out tag))
                {
                    contraBroker = tag.Value;
                }
                else if (msg.ContraGrp.Count > 0)
                {
                    contraBroker = msg.ContraGrp[0].ContraBroker;
                }
                else if (msg.TargetCompID != null && msg.TargetCompID != String.Empty)
                {
                    contraBroker = msg.TargetCompID;
                }
                else if (msg.OnBehalfOfCompID != null && msg.OnBehalfOfCompID != String.Empty)
                {
                    contraBroker = msg.OnBehalfOfCompID;
                }
                else if (exec.TagValuesParsed.TryGetValue(115, out tag) && tag.Value != String.Empty)
                {
                    contraBroker = tag.Value;
                }
                else if (exec.TagValuesParsed.TryGetValue(57, out tag) && tag.Value != String.Empty)
                {
                    contraBroker = tag.Value;
                }
                else if (exec.TagValuesParsed.TryGetValue(100, out tag))
                {
                    contraBroker = tag.Value;
                }


                // account
                string account = "DEFAULT";
                if (msg.Account != String.Empty)
                {
                    if (msg.Account == "NELIQUID")
                        account = "LTI005";
                    else
                        account = msg.Account;
                }

                // text
                List<string> text = new List<string>();
                if(msg.Text != String.Empty)
                    text.Add(msg.Text);


                bool isAggressor = false;
                bool isHidden = false;
                bool isInternal = false;

                LiquidViewConstants.ExchangeMICs? routedExchange = null;
                LiquidViewConstants.TradeTypes? tradeType = null;

                // get settings from flag
                string flag9882 = null;
                if (exec.TagValuesParsed.TryGetValue(9882, out tag))
                {
                    flag9882 = tag.Value;
                    ParseFlags(exec, executionExchange, ref flag9882, text, out isAggressor, out isHidden, out isInternal, out routedExchange, out tradeType);
                }
                else
                {
                    isAggressor = true;
                }

                // get extra flags and append to TradeText                    
                // Tag(9621) -- ECNAccessFee
                if (exec.TagValuesParsed.TryGetValue(9621, out tag))
                {
                    text.Add("MTFAccessFee(" + tag.Value + ")");
                }
                // Tag(9730) -- ECNAccessFee
                if (exec.TagValuesParsed.TryGetValue(9730, out tag))
                {
                    text.Add("TradeLiquidityIndicator(" + tag.Value + ")");
                }

                // US trade
                if (LiquidViewConstants.USExchanges.Contains(executionExchange))
                {
                    if (currency == String.Empty)
                    {   
                        currency = "USD";
                    }

                    msg.Instrument.Symbol = msg.Instrument.Symbol.Replace('/', '.');

#if !DEBUG
                    int result = m_Linq.ImportTradeUSStock(
                        ClientName,
                        msg.OrderID,
                        msg.ExecID,
                        executionExchange.ToString(),
                        msg.OrderID,
                        msg.ExecID,
                        account,
                        msg.Instrument.Symbol,
                        msg.Side == RapidAddition.FIXObjectModel.FIX50.ESide.eBuy ? (long)msg.LastQty.Value : -(long)msg.LastQty.Value,
                        price,
                        msg.TransactTime.Value,
                        contraBroker, // coutnerpart code
                        isAggressor, // is aggressive trade
                        false, // is manual trade
                        isInternal, // is an internalised trade
                        isHidden, // hidden flag
                        tradeType.HasValue ? tradeType.ToString() : null, // trade type
                        null, // broker code
                        String.Join("|", text.ToArray()),
                        routedExchange.HasValue ? routedExchange.ToString() : null, // routed exchange
                        flag9882, // trade flags
                        exec.TargetCompID != String.Empty ? exec.TargetCompID : null); // user

                    if (result == 0)
                    {
                        // trade inserted
                    }
                    else if (result == 1)
                    {
                        m_Linq.ExceptionHandlerThrow(ClientName, "ProcessExecutionReport Filtered(" + result + ") trade on insert of MsgExecutionReport(8) - " + exec.Message, null);
                    }
                    else if (result == -1)
                    {
                        m_Linq.ExceptionHandlerThrow(ClientName, "ProcessExecutionReport Failed(" + result + ") (general) on insert of MsgExecutionReport(8) - " + exec.Message, null);
                    }
                    else if (result == -2)
                    {
                        m_Linq.ExceptionHandlerThrow(ClientName, "ProcessExecutionReport Failed(" + result + ") to find StockId from US stock symbol " + msg.Instrument.Symbol + " on insert of MsgExecutionReport(8) - " + exec.Message, null);
                    }
                    else if (result == -3)
                    {
                        m_Linq.ExceptionHandlerThrow(ClientName, "ProcessExecutionReport Failed(" + result + ") to find ExchangeMIC of " + exchangeMIC + " on insert of MsgExecutionReport(8) - " + exec.Message, null);
                    }
                    else if (result == -4)
                    {
                        m_Linq.ExceptionHandlerThrow(ClientName, "ProcessExecutionReport Failed(" + result + ") to complete PutTrade on insert of MsgExecutionReport(8) - " + exec.Message, null);
                    }
                    else
                    {
                        m_Linq.ExceptionHandlerThrow(ClientName, "ProcessExecutionReport some other failure(" + result + ") on insert of MsgExecutionReport(8) - " + exec.Message, null);
                    }
#endif
                }
                // European or UK trade
                else
                {
#if !DEBUG
                    int result = m_Linq.ImportTradeByUMTF(
                        ClientName,
                        msg.OrderID,
                        msg.ExecID,
                        executionExchange.ToString(),
                        msg.OrderID,
                        msg.ExecID,
                        account,
                        currency != String.Empty ? currency : null,
                        umtf,
                        msg.Side == RapidAddition.FIXObjectModel.FIX50.ESide.eBuy ? (long)msg.LastQty.Value : -(long)msg.LastQty.Value,
                        price,
                        msg.TransactTime.Value,
                        contraBroker,
                        isAggressor,
                        false,
                        isInternal,
                        String.Empty,
                        String.Join("|", text.ToArray()),
                        isHidden, // hidden flag
                        tradeType.HasValue ? tradeType.ToString() : null, // trade type       
                        routedExchange.HasValue ? routedExchange.ToString() : null, // routed exchange
                        flag9882, // trade flags
                        exec.TargetCompID != String.Empty ? exec.TargetCompID : null); // user


                    if (result == 0)
                    {
                        // trade inserted
                    }
                    else if (result == 1)
                    {
                        m_Linq.ExceptionHandlerThrow(ClientName, "ProcessExecutionReport Filtered(" + result + ") broker trade on insert of MsgExecutionReport(8) - " + exec.Message, null);
                    }
                    else if (result == -1)
                    {
                        m_Linq.ExceptionHandlerThrow(ClientName, "ProcessExecutionReport Failed(" + result + ")(general) on insert of MsgExecutionReport(8) - " + exec.Message, null);
                    }
                    else if (result == -2)
                    {
                        m_Linq.ExceptionHandlerThrow(ClientName, "ProcessExecutionReport Failed(" + result + ") to find StockId from UMTF code " + msg.Instrument.Symbol + " on insert of MsgExecutionReport(8) - " + exec.Message, null);
                    }
                    else if (result == -3)
                    {
                        m_Linq.ExceptionHandlerThrow(ClientName, "ProcessExecutionReport Failed(" + result + ") to find ExchangeMIC of " + exchangeMIC + " on insert of MsgExecutionReport(8) - " + exec.Message, null);
                    }
                    else if (result == -4)
                    {
                        m_Linq.ExceptionHandlerThrow(ClientName, "ProcessExecutionReport Failed(" + result + ") to find default Local Listing and Currency for " + msg.Instrument.Symbol + " on " + exchangeMIC + " on insert of MsgExecutionReport(8) - " + exec.Message, null);
                    }
                    else if (result == -5)
                    {
                        m_Linq.ExceptionHandlerThrow(ClientName, "ProcessExecutionReport Failed(" + result + ") to complete PutGtrade on insert of MsgExecutionReport(8) - " + exec.Message, null);
                    }
                    else if (result == -6)
                    {
                        m_Linq.ExceptionHandlerThrow(ClientName, "ProcessExecutionReport Failed(" + result + ") to complete PutTrade on insert of MsgExecutionReport(8) - " + exec.Message, null);
                    }
                    else
                    {
                        m_Linq.ExceptionHandlerThrow(ClientName, "ProcessExecutionReport some other failure(" + result + ") on insert of MsgExecutionReport(8) - " + exec.Message, null);
                    }
#endif
                }
            }

        }




        private bool TryGetUMTFFromISIN(LiquidViewConstants.ExchangeMICs executionExchange, string currency, string isin, string symbol, out string umtf)
        {
            ViewInstrumentsStocksListing result = m_Linq.ViewInstrumentsStocksListings.SingleOrDefault(
                row =>
                    row.ExchangeMIC == executionExchange.ToString()
                    && row.ListingCurrency == currency
                    && row.ISIN == isin
                );

            if (result != default(ViewInstrumentsStocksListing))
            {
                if (result.UMTF != null && result.UMTF != String.Empty)
                {
                    umtf = result.UMTF;
                    return true;
                }
            }

            umtf = String.Empty;
            return false;
        }

        private bool TryGetExchangeMIC(string exchangeMIC, string senderCompId, out LiquidViewConstants.ExchangeMICs executionExchange)
        {
            if (senderCompId == "BATS")
            {
                executionExchange = LiquidViewConstants.ExchangeMICs.BATE;
                return true;
            }
            else if (senderCompId == "CHIX")
            {
                executionExchange = LiquidViewConstants.ExchangeMICs.CHIX;
                return true;
            }
            else if (senderCompId == "LSE")
            {
                executionExchange = LiquidViewConstants.ExchangeMICs.XLON;
                return true;
            }
            executionExchange = LiquidViewConstants.ExchangeMICs.XXXX;
            return false;
        }



        public bool IsUSSymbol(string symbol)
        {
            // is US stock?
            if (!symbol.Contains('.'))
            {
                return true;
            }
            return false;
        }


        public bool TryGetUMTFfromSterling(string symbol, out string umtf)
        {
            if (!symbol.Contains('.'))
            {
                umtf = String.Empty;
                return false;
            }
            symbol = symbol.Replace("/", "");
            int pos = symbol.LastIndexOf('.');
            string sterlingExchange = symbol.Substring(pos + 1);
            switch (sterlingExchange)
            {
                case "LN":
                    umtf = symbol.Substring(0, pos) + "l";
                    return true;
                case "PA":
                    umtf = symbol.Substring(0, pos) + "p";
                    return true;
                case "AM":
                    umtf = symbol.Substring(0, pos) + "a";
                    return true;
                case "DB":
                    umtf = symbol.Substring(0, pos) + "d";
                    return true;
                case "BI":
                    umtf = symbol.Substring(0, pos) + "m";
                    return true;
                case "ZU":
                    umtf = symbol.Substring(0, pos) + "z";
                    return true;
                case "CO":
                    umtf = symbol.Substring(0, pos) + "c";
                    return true;
                case "BR":
                    umtf = symbol.Substring(0, pos) + "b";
                    return true;
                case "LI":
                    umtf = symbol.Substring(0, pos) + "u";
                    return true;
                case "HS":
                    umtf = symbol.Substring(0, pos) + "h";
                    return true;
                case "MD":
                    umtf = symbol.Substring(0, pos) + "e";
                    return true;
                case "OS":
                    umtf = symbol.Substring(0, pos) + "o";
                    return true;
                case "ST":
                    umtf = symbol.Substring(0, pos) + "s";
                    return true;
                case "VE":
                    umtf = symbol.Substring(0, pos) + "v";
                    return true;
                case "TO":
                    umtf = symbol.Substring(0, pos) + "t";
                    return true;
                default:
                    umtf = String.Empty;
                    return false;
            }
        }




        private void ParseFlags(RapidAddition.FIXEngine.CFIXMessage exec, LiquidViewConstants.ExchangeMICs executionExchange, ref string flag9882, List<string> text, out bool isAggressor, out bool isHidden, out bool isInternal, out LiquidViewConstants.ExchangeMICs? routedExchange, out LiquidViewConstants.TradeTypes? tradeType)
        {
            isAggressor = false;
            isHidden = false;
            isInternal = false;
            routedExchange = null;
            tradeType = null;

            if (executionExchange == LiquidViewConstants.ExchangeMICs.CHIX)
            {
                switch (flag9882)
                {
                    case "A":
                        text.Add("Passive");
                        return;
                    case "R":
                        text.Add("Aggressive");
                        isAggressor = true;
                        return;
                    case "D":
                        text.Add("Hidden");
                        isAggressor = true;
                        isHidden = true;
                        return;
                    case "X":
                        text.Add("Routed");
                        routedExchange = LiquidViewConstants.ExchangeMICs.XXXX;
                        return;
                    default:
                        m_Linq.ExceptionHandlerThrow(ClientName, "ProcessExecutionReport ExecutionReport from Chi-X Europe has unknown Flag(9882)='" + flag9882 + "' - " + exec.Message, null);
                        return;
                }
            }
            else if (executionExchange == LiquidViewConstants.ExchangeMICs.BATE)
            {
                switch (flag9882)
                {
                    case "A":
                        text.Add("Passive");
                        return;
                    case "R":
                        text.Add("Aggressive");
                        isAggressor = true;
                        return;
                    case "AD":
                    case "AM":
                        text.Add("Hidden Passive");
                        isHidden = true;
                        return;
                    case "RD":
                    case "RM":
                        text.Add("Hidden Aggressive");
                        isAggressor = true;
                        isHidden = true;
                        return;
                    case "X":
                        text.Add("Routed");
                        routedExchange = LiquidViewConstants.ExchangeMICs.XXXX;
                        return;
                    default:
                        m_Linq.ExceptionHandlerThrow(ClientName, "ProcessExecutionReport ExecutionReport from BATS Europe has unknown Flag(9882)='" + flag9882 + "' - " + exec.Message, null);
                        return;
                }
            }
            // London Stock Exchange
            else if (executionExchange == LiquidViewConstants.ExchangeMICs.XLON)
            {
                switch (flag9882)
                {
                    case "1":
                        text.Add("Passive");
                        return;
                    case "2":
                        text.Add("Aggressive");
                        isAggressor = true;
                        return;
                    case "4":
                        text.Add("Uncrossing trade");
                        isAggressor = true;
                        tradeType = LiquidViewConstants.TradeTypes.UT;
                        return;
                    default:
                        m_Linq.ExceptionHandlerThrow(ClientName, "ProcessExecutionReport ExecutionReport from LSE has unknown Flag(9882)='" + flag9882 + "' - " + exec.Message, null);
                        return;
                }
            }
            /// ARCA
            else if (executionExchange == LiquidViewConstants.ExchangeMICs.ARCX)
            {
                switch (flag9882)
                {
                    case "A":
                        text.Add("Added");
                        break;
                    case "B":
                        text.Add("Passive while hidden");
                        isHidden = true;
                        break;
                    case "R":
                        text.Add("Removed");
                        isAggressor = true;
                        break;
                    case "O":
                        text.Add("Neutral, Order executed in an auction");
                        isAggressor = true;
                        tradeType = LiquidViewConstants.TradeTypes.UT;
                        break;
                    case "X":
                        text.Add("Routed to another venue");
                        routedExchange = LiquidViewConstants.ExchangeMICs.XXXX;
                        break;
                    case "F":
                        text.Add("Routed to NYSE where the order was liquidity adding at NYSE");
                        routedExchange = LiquidViewConstants.ExchangeMICs.XNYS;
                        break;
                    case "N":
                        text.Add("Routed to NYSE where the order was liquidity taking at NYSE");
                        routedExchange = LiquidViewConstants.ExchangeMICs.XNYS;
                        isAggressor = true;
                        break;
                    case "C":
                        text.Add("Routed to NYSE where the order participated in the opening or re-opening");
                        routedExchange = LiquidViewConstants.ExchangeMICs.XNYS;
                        tradeType = LiquidViewConstants.TradeTypes.OUT;
                        break;
                    default:
                        m_Linq.ExceptionHandlerThrow(ClientName, "ProcessExecutionReport ExecutionReport from Arca has unknown Flag(9882)='" + flag9882 + "' - " + exec.Message, null);
                        break;
                }
            }
            /// BATS
            else if (executionExchange == LiquidViewConstants.ExchangeMICs.BATS)
            {
                switch (flag9882)
                {
                    case "A":
                        text.Add("Added Liquidity");
                        break;
                    case "R":
                        text.Add("Removed Liquidity");
                        isAggressor = true;
                        break;
                    case "X":
                        text.Add("Routed");
                        routedExchange = LiquidViewConstants.ExchangeMICs.XXXX;
                        break;
                    case "Q":
                        text.Add("Added liquidity via delivery from exchange where BATS displays its quote to the consolidated quote (E.g. NSX)");
                        break;
                    default:
                        m_Linq.ExceptionHandlerThrow(ClientName, "ProcessExecutionReport ExecutionReport from BATS US has unknown Flag(9882)='" + flag9882 + "' - " + exec.Message, null);
                        break;
                }
            }
            /// Nasdaq
            else if (executionExchange == LiquidViewConstants.ExchangeMICs.XNAS)
            {
                switch (flag9882)
                {
                    case "A":
                        text.Add("Added");
                        break;
                    case "B":
                        text.Add("Routed to BX");
                        break;
                    case "R":
                        text.Add("Removed");
                        isAggressor = true;
                        break;
                    case "X":
                        text.Add("Routed");
                        routedExchange = LiquidViewConstants.ExchangeMICs.XXXX;
                        break;
                    case "D":
                        text.Add("DOT");
                        break;
                    case "F":
                        text.Add("Added or Opening Trade (on NYSE)");
                        routedExchange = LiquidViewConstants.ExchangeMICs.XNYS;
                        tradeType = LiquidViewConstants.TradeTypes.OUT;
                        break;
                    case "G":
                        text.Add("Odd Lot or On-Close order (on NYSE)");
                        routedExchange = LiquidViewConstants.ExchangeMICs.XNYS;
                        tradeType = LiquidViewConstants.TradeTypes.CUT;
                        break;
                    case "J":
                        text.Add("Non-displayed and added liquidity");
                        isHidden = true;
                        break;
                    case "O":
                        text.Add("Open Cross (billable)");
                        isAggressor = true;
                        tradeType = LiquidViewConstants.TradeTypes.OUT;
                        break;
                    case "M":
                        text.Add("Open Cross (non-billable)");
                        tradeType = LiquidViewConstants.TradeTypes.OUT;
                        break;
                    case "C":
                        text.Add("Close Cross (billable)");
                        isAggressor = true;
                        tradeType = LiquidViewConstants.TradeTypes.CUT;
                        break;
                    case "L":
                        text.Add("Close Cross (non-billable)");
                        tradeType = LiquidViewConstants.TradeTypes.CUT;
                        break;
                    case "H":
                        text.Add("Halt Cross (billable)");
                        isAggressor = true;
                        tradeType = LiquidViewConstants.TradeTypes.UT;
                        break;
                    case "I":
                        text.Add("Intraday / Post market Cross");
                        isAggressor = true;
                        tradeType = LiquidViewConstants.TradeTypes.UT;
                        break;
                    case "K":
                        text.Add("Halt Cross (non-billable)");
                        tradeType = LiquidViewConstants.TradeTypes.UT;
                        break;
                    case "Y":
                        text.Add("Re-Routed to NYSE");
                        routedExchange = LiquidViewConstants.ExchangeMICs.XNYS;
                        break;
                    default:
                        m_Linq.ExceptionHandlerThrow(ClientName, "ProcessExecutionReport ExecutionReport from Nasdaq has unknown Flag(9882)='" + flag9882 + "' - " + exec.Message, null);
                        break;
                }
            }
            /// NYSE
            else if (executionExchange == LiquidViewConstants.ExchangeMICs.XNYS)
            {
                switch (flag9882)
                {
                    case "1":
                        text.Add("Removed");
                        isAggressor = true;
                        break;
                    case "2":
                        text.Add("Added");
                        break;
                    case "4":
                        text.Add("Opening Added Prior day GTC");
                        tradeType = LiquidViewConstants.TradeTypes.OUT;
                        break;
                    case "5":
                        text.Add("Opening Added");
                        tradeType = LiquidViewConstants.TradeTypes.OUT;
                        break;
                    case "6":
                        text.Add("Closing Removed");
                        tradeType = LiquidViewConstants.TradeTypes.CUT;
                        break;
                    case "9":
                        text.Add("Odd lot");
                        break;
                    default:
                        text.Add("Routed - OriginalFlag=" + flag9882 + "");
                        routedExchange = LiquidViewConstants.ExchangeMICs.XXXX;
                        flag9882 = "X";
                        // this doesn't apply for NYSE
                        // flags are numeric if on the NYSE, or anything else wouldn't mean it was routed
                        // Not sure what woudl happen for r9outed to Edge with a numeric flag
                        //m_Linq.ExceptionHandlerThrow(ClientName, "ProcessExecutionReport ExecutionReport from NYSE has unknown Flag(9882)='" + flag9882 + "' - " + exec.Message, null);
                        break;
                }
            }
            /// AMEX
            else if (executionExchange == LiquidViewConstants.ExchangeMICs.XASE)
            {
                switch (flag9882)
                {
                    case "1":
                    case "R":
                        text.Add("Removed");
                        isAggressor = true;
                        flag9882 = "1";
                        break;
                    case "2":
                    case "A":
                        text.Add("Added");
                        flag9882 = "2";
                        break;
                    case "X":
                        text.Add("Routed");
                        routedExchange = LiquidViewConstants.ExchangeMICs.XXXX;
                        break;
                    case "6":
                    case "C":
                        text.Add("Neutral, order executed in the closing auction");
                        tradeType = LiquidViewConstants.TradeTypes.CUT;
                        flag9882 = "6";
                        break;
                    case "5":
                        text.Add("Neutral, order executed in the opening auction");
                        tradeType = LiquidViewConstants.TradeTypes.OUT;
                        break;
                    case "9":
                        text.Add("Odd lot transaction");
                        break;
                    default:
                        m_Linq.ExceptionHandlerThrow(ClientName, "ProcessExecutionReport ExecutionReport from Amex has unknown Flag(9882)='" + flag9882 + "' - " + exec.Message, null);
                        break;
                }
            }
            /// Direct Edge
            else if (executionExchange == LiquidViewConstants.ExchangeMICs.EDGX || executionExchange == LiquidViewConstants.ExchangeMICs.EDGA)
            {
                switch (flag9882)
                {
                    case "A":
                        text.Add("Execution added liquidity to INET book (Tape A / B / C), Routed to Nasdaq, adds liquidity");
                        break;
                    case "B":
                        text.Add("Execution added liquidity (Tape B)");
                        break;
                    case "C":
                        text.Add("Routed to Nasdaq BX (Tapes A & C), removes liquidit");
                        isAggressor = true;
                        routedExchange = LiquidViewConstants.ExchangeMICs.XNAS;
                        break;
                    case "D":
                        text.Add("Listed Route removing liquidity from NYSE DOT (Tape A), Routed or Re-routed to NYSE, removes liquidity");
                        isAggressor = true;
                        routedExchange = LiquidViewConstants.ExchangeMICs.XNYS;
                        break;
                    case "E":
                        text.Add("Internal Match (Tape A / B / C, Add and Remove MMIDs are the same)");
                        isInternal = true;
                        break;
                    case "F":
                        text.Add("Listed Route adding liquidity to NYSE DOT (Tape A)");
                        routedExchange = LiquidViewConstants.ExchangeMICs.XNYS;
                        break;
                    case "G":
                        text.Add("Routed to ARCA (Tapes A & C), removes liquidity");
                        isAggressor = true;
                        routedExchange = LiquidViewConstants.ExchangeMICs.ARCX;
                        break;
                    case "H":
                        text.Add("Execution added liquidity from Hidden order (Tape A / B / C, EDGA only)");
                        isHidden = true;
                        break;
                    case "I":
                        text.Add("Order routed to EDGA (for EDGX orders) or to EDGX (for EDGA orders)");
                        if (executionExchange == LiquidViewConstants.ExchangeMICs.EDGX)
                            routedExchange = LiquidViewConstants.ExchangeMICs.EDGA;
                        else
                            routedExchange = LiquidViewConstants.ExchangeMICs.EDGX;
                        break;
                    case "J":
                        text.Add("Routed to Nasdaq, removes liquidity");
                        isAggressor = true;
                        routedExchange = LiquidViewConstants.ExchangeMICs.XNAS;
                        break;
                    case "K":
                        text.Add("Routed to BATS Using ROBA Order Type (EDGA + BATS)");
                        routedExchange = LiquidViewConstants.ExchangeMICs.BATS;
                        break;
                    case "L":
                        text.Add("Routed to Nasdaq using INET Order Type, removes liquidity (Tapes A & C)");
                        routedExchange = LiquidViewConstants.ExchangeMICs.XNAS;
                        break;
                    case "M":
                        text.Add("Add Liquidity on LavaFlow");
                        break;
                    case "N":
                        text.Add("Execution removed liquidity (Tape B / C)");
                        isAggressor = true;
                        break;
                    case "O":
                        text.Add("Routed to the Nasdaq Opening Cross (Tape C)");
                        routedExchange = LiquidViewConstants.ExchangeMICs.XNAS;
                        tradeType = LiquidViewConstants.TradeTypes.OUT;
                        break;
                    case "P":
                        text.Add("Add Liquidity on EDGX via an EDGA-originated ROUC Order Type");
                        break;
                    case "Q":
                        text.Add("Routed using ROUQ or ROUC Order Types");
                        routedExchange = LiquidViewConstants.ExchangeMICs.XXXX;
                        break;
                    case "R":
                        text.Add("Re-Routed via Routing Destination (Tape A / B / C)");
                        routedExchange = LiquidViewConstants.ExchangeMICs.XXXX;
                        break;
                    case "S":
                        text.Add("Execution for an ISO order routed externally as ISO ( Tape A / B / C)");
                        routedExchange = LiquidViewConstants.ExchangeMICs.XXXX;
                        break;
                    case "T":
                        text.Add("Routed using ROUD/ROUE Order Type");
                        isHidden = true;
                        break;
                    case "U":
                        text.Add("Remove Liquidity on LavaFlow");
                        isAggressor = true;
                        break;
                    case "V":
                        text.Add("Execution added liquidity (Tape A)");
                        break;
                    case "W":
                        text.Add("Execution removed liquidity (Tape A)");
                        isAggressor = true;
                        break;
                    case "X":
                        text.Add("Route to External Venue (Tape B / C)");
                        routedExchange = LiquidViewConstants.ExchangeMICs.XXXX;
                        break;
                    case "Y":
                        text.Add("Execution added liquidity (Tape C)");
                        break;
                    case "Z":
                        text.Add("Route to an IOI destination (Tape A / B / C, ROUZ ExecBroker only)");
                        routedExchange = LiquidViewConstants.ExchangeMICs.XXXX;
                        break;
                    case "2":
                        text.Add("Routed to Nasdaq using INET Order Type, removes liquidity (Tape B)");
                        isAggressor = true;
                        routedExchange = LiquidViewConstants.ExchangeMICs.XNAS;
                        break;
                    case "3":
                    case "4":
                        text.Add("Add Liquidity - Pre & Post Market");
                        tradeType = LiquidViewConstants.TradeTypes.UT;
                        break;
                    case "5":
                        text.Add("Customer Internalization - Pre & Post Market");
                        isInternal = true;
                        tradeType = LiquidViewConstants.TradeTypes.UT;
                        break;
                    case "6":
                        text.Add("Remove Liquidity - Pre & Post Market (All Tapes)");
                        isAggressor = true;
                        tradeType = LiquidViewConstants.TradeTypes.UT;
                        break;
                    case "7":
                        text.Add("Routed - Pre & Post Market");
                        routedExchange = LiquidViewConstants.ExchangeMICs.XXXX;
                        tradeType = LiquidViewConstants.TradeTypes.UT;
                        break;
                    default:
                        m_Linq.ExceptionHandlerThrow(ClientName, "ProcessExecutionReport ExecutionReport from Direct Edge has unknown Flag(9882)='" + flag9882 + "' - " + exec.Message, null);
                        break;
                }
            }
        }



        private bool TryGetExchangeMIC(string exchangeMIC, out LiquidViewConstants.ExchangeMICs executionExchange)
        {
            switch (exchangeMIC)
            {
                case "ARCA":
                case "ARCA=":
                case "ARCX":
                    executionExchange = LiquidViewConstants.ExchangeMICs.ARCX;
                    return true;
                case "NSDQ":
                case "XNAS":
                    executionExchange = LiquidViewConstants.ExchangeMICs.XNAS;
                    return true;
                case "NYSE":
                case "XNYS":
                    executionExchange = LiquidViewConstants.ExchangeMICs.XNYS;
                    return true;
                case "AMEX":
                case "XASE":
                    executionExchange = LiquidViewConstants.ExchangeMICs.XASE;
                    return true;
                case "LSE":
                case "LSEFOK":
                case "XLON":
                    executionExchange = LiquidViewConstants.ExchangeMICs.XLON;
                    return true;
                case "BATS":
                    executionExchange = LiquidViewConstants.ExchangeMICs.BATS;
                    return true;
                case "BATE":
                case "BATSCYCLE":
                case "BATSEU":
                case "BATSPP":
                case "BATSRC":
                case "BATSRL":
                    executionExchange = LiquidViewConstants.ExchangeMICs.BATE;
                    return true;
                case "EDGA":
                    executionExchange = LiquidViewConstants.ExchangeMICs.EDGA;
                    return true;
                case "EDGX":
                    executionExchange = LiquidViewConstants.ExchangeMICs.EDGX;
                    return true;
                case "CHIX":
                case "CHIXEU":
                    executionExchange = LiquidViewConstants.ExchangeMICs.CHIX;
                    return true;
                case "FBCO":
                    executionExchange = LiquidViewConstants.ExchangeMICs.FBCO;
                    return true;
                case "XXXX":
                default:
                    executionExchange = LiquidViewConstants.ExchangeMICs.XXXX;
                    return false;
            }
        }

        public void ProcessState(RapidAddition.FIXEngine.CFIXSession session, RapidAddition.FIXEngine.EFIXSessionState state)
        {
            string message;
            if (state == RapidAddition.FIXEngine.EFIXSessionState.Connecting)
            {
                message = String.Format("Connecting to {0}:{1}", session.Conversation.CounterParty.IPAddress, session.Conversation.CounterParty.Port);
            }
            else if (state == RapidAddition.FIXEngine.EFIXSessionState.Disconnecting)
            {
                message = String.Format("Disconnecting from {0}:{1}", session.Connection.IPAdress, session.Connection.Port);
            }
            else if (state == RapidAddition.FIXEngine.EFIXSessionState.Listening)
            {
                message = String.Format("Listening on {0}:{1}", session.Connection.IPAdress, session.Connection.Port);
            }
            else if (state == RapidAddition.FIXEngine.EFIXSessionState.LoggedOn)
            {
                message = String.Format("LoggedOn as {0} to {1}:{2}", session.Conversation.Party.CompID, session.Connection.IPAdress, session.Connection.Port);
            }
            else if (state == RapidAddition.FIXEngine.EFIXSessionState.LoggedOut)
            {
                message = "LoggedOut";
            }
            else if (state == RapidAddition.FIXEngine.EFIXSessionState.RecievedLogout)
            {
                message = String.Format("RecievedLogout from {0} on {1}:{2}", session.Conversation.CounterParty.CompID, session.Conversation.CounterParty.IPAddress, session.Conversation.CounterParty.Port);
            }
            else if (state == RapidAddition.FIXEngine.EFIXSessionState.Resynching)
            {
                message = String.Format("RecievedLogout from {0} on {1}:{2}", session.Conversation.CounterParty.CompID, session.Conversation.CounterParty.IPAddress, session.Conversation.CounterParty.Port);
            }
            else if (state == RapidAddition.FIXEngine.EFIXSessionState.SentLogonWaitingResponse)
            {
                message = String.Format("SentLogonWaitingResponse as {0} to {1} on {2}:{3}", session.Conversation.Party.CompID, session.Conversation.CounterParty.CompID, session.Conversation.CounterParty.IPAddress, session.Conversation.CounterParty.Port);
            }
            else if (state == RapidAddition.FIXEngine.EFIXSessionState.SentLogoutWaitingResponse)
            {
                message = String.Format("SentLogoutWaitingResponse from {0} on {1}:{2}", session.Conversation.CounterParty.CompID, session.Conversation.CounterParty.IPAddress, session.Conversation.CounterParty.Port);
            }
            else
            {
                message = state.ToString();
            }

            try
            {
                m_Linq.LogGeneral(ClientName, "ProcessState", state.ToString(), message, null, null, null, null, null, null);
            }
            catch (Exception e)
            {
                Console.WriteLine(e);
            }
        }



        #endregion

        #region IDisposable Members

        public void Dispose()
        {
            m_Linq.Dispose();
        }

        #endregion

        #region IStorage Members

        public void LogGeneral(string category, string message)
        {
            throw new NotImplementedException();
        }

        public void LogException(string category, string message)
        {
            throw new NotImplementedException();
        }

        #endregion
    }

}
